<?php

/**
 * @author hungnq@younetco.com
 */
class Tab_Form_Entry extends YouNet_Form implements Core_Model_IEntryFields
{
	const URL_YOUTUBE_PARTERN = '/(https?:\/\/(www\.)?youtube\.com\/.*v=\w+.*)|(https?:\/\/youtu\.be\/\w+.*)/';
	const EDIT	= 1;
	const INSERT= 0;
	
	protected $_element_decorators = array(
		'ViewHelper',
		'Description',
		'Errors',
		array('HtmlTag', array('tag' => 'dd')),
		array('Label', array('tag' => 'dt')),
	);
	
	protected $_file_decorators = array(
		'File',
		'Description',
		'Errors',
		array('HtmlTag', array('tag' => 'dd')),
		array('Label', array('tag' => 'dt')),
	);
	
	protected $_id_contest;
	protected $_is_edit;
	protected $_validate_script;
	protected $_is_use_fullname = true;
	protected $_fullname_id		= 0;
	
	public function __construct($options = null, $id_contest = null, $is_edit = 0)
	{
		$this->_id_contest	=	$id_contest;
		$this->_is_edit		=	$is_edit;
		parent::__construct($options);
	}

	public function init()
	{
		$this->setMethod('post');
		$this->setAttrib('class','sm_form standard tab');
		$this->setAttrib('id','entry_form');	
		if(!$this->_is_edit)
		{
			if( APP_INSTANCE == APP_INSTANCE_VIDEO )
			{
				$this->__initVideo();
			}
			else
			{
				$this->__initImage();
			}
		}
		
		$this->addElement('text','title',array(
			'label'		=> $this->getTranslator()->_('LABEL_TITLE'),
			'required'	=> true,
			'class'		=>'required length_longest',
			//'maxlength' => 255,
			'filters'	=> array('StringTrim'),
			'validators'=> array(
				array('StringLength', false, array(
                    'min' => 1, 
                    'max' => 255,
                    'encoding' => 'UTF-8'
                ))
			)
		));
		$msg = $this->getTranslator()->_('ERROR_EXCEED_MAXLENGTH_TITLE');
		
		$this->title->getValidator('StringLength')->setMessages(array(
			Zend_Validate_StringLength::TOO_LONG => $msg
		));
		
		$this->addElement('textarea', 'description', array(
			'label' => $this->getTranslator()->_('LABEL_DESCRIPTION'),
            'class' => 'length_longest',
			'cols' => 50,
			'rows' => 4,
			'filters' => array('StringTrim'),
            'validators'=> array(
				array('StringLength', false, array(
                    'max' => 1000,
                    'encoding' => 'UTF-8'
                ))
			)
		));
        
		$this->description->getValidator('StringLength')->setMessages(array(
			Zend_Validate_StringLength::TOO_LONG => $this->getTranslator()->_('ERROR_EXCEED_MAXLENGTH_DESCRIPTION')
		));

		
		/* Init dynamic contest fields */
		$this->initContestFields($this->_id_contest);
		
		if(!$this->_is_edit)
		{
            $contest = Core_Model_DbTable_Contests::getInstance()->findOne($this->_id_contest);
            if ($contest->is_using_captcha)
            {
                $recaptcha= new Zend_Service_ReCaptcha(
                    RECAPTCHA_PUBLIC_KEY,
                    RECAPTCHA_PRIVATE_KEY,
                    null,
                    array(
                        'theme' => 'white'
                    )
                );
                $recaptcha_it_translation = array(
                    'instructions_visual' => $this->getTranslator()->_('instructions_visual'),
                    'incorrect_try_again' => $this->getTranslator()->_('incorrect_try_again')
                );
                $recaptcha->setOption('custom_translations', $recaptcha_it_translation);
                $captcha = $this->createElement(
                    'Captcha', 'ReCaptcha', array(
                    'captcha' => array(
                        'captcha' => 'ReCaptcha',
                        'service' => $recaptcha
                    ))
                );
                $captcha->setLabel('FIELD_ENTER_CAPTCHA');
                $this->addElement($captcha);
            }
        
			$this->addElement('hidden', 'terms_and_conditions', array(
				'description' => "<span class='terms_des' >".$this->getTranslator()->_('LABEL_TERMS_AND_CONDITIONS_FIRST') . '<a href="#" id="show_terms_and_conditions">'.$this->getTranslator()->_('LABEL_TERMS_AND_CONDITIONS_LAST') .'</a>.</span>',
                'ignore' => true,
                'decorators' => array(
                    array('Description', array('escape'=>false, 'tag'=>'')),
                )
			));
			
//			$this->getElement('terms_and_conditions')->setDecorators(array(array('ViewScript', array(
//					'viewScript' => 'decorator/terms_and_conditions.phtml'
//			))));
		} else {
            $this->addElement('button', 'back', array(
                'label' => $this->getTranslator()->_('LABEL_BACK'),
                'class' => 'graybutton btn_back',
                'decorators' => array('ViewHelper')
            ));
        }
		
		$this->addElement('submit', 'submit', array(
			'label' => $this->getTranslator()->_('LABEL_SUBMIT'),
			'class' => 'fanpage_button',
			'decorators' => array('ViewHelper')
		));
        $this->addElement('button', 'reset', array(
			'label' => $this->getTranslator()->_('LABEL_RESET'),
			'class' => 'fanpage_button btn_reset',
			'decorators' => array('ViewHelper'),
            'onclick'   => "$('#link_submit_entry').click();"
		));
		
		 $this->addDisplayGroup(array('submit', 'reset', 'back'), 'submitButtons', array(
            'decorators' => array(
                'FormElements',
				'DtDdWrapper',
            ),
        ));
	}
	
	private function __initVideo()
	{
		$this->addElement('text', 'image', array(
			'label'		=> 'LABEL_IMAGE',
            'class'     => 'length_longest',
			'required'	=> true,
			'filters'	=> array('StringTrim')
		));
		$this->image->addValidator(new Zend_Validate_StringLength(array('max' => 255)));
		$this->image->addValidator('regex', true,
			array(
				'pattern' =>self::URL_YOUTUBE_PARTERN,
				'messages'=>array(
					'regexNotMatch'=>'ERROR_YOUTUBE_LINK_IS_INVALID'
				)
			)
		);
	}
	private function __initImage()
	{
		$image = new YouNet_Form_Element_File('image');
		$image->setDecorators($this->_file_decorators); //_file_decorators
		$image->setLabel('LABEL_IMAGE')
				->setDestination(UPLOAD_PATH);
		$image->setDescription(".jpeg | .jpg | .png <=1MB");
		// ensure only 1 file
		$image->addValidator('Count', false, 1);
		// limit to 200kb
		$image->addValidator('Size', false, '1MB');
		// only JPEG, PNG, and GIFs
		$image->addValidator('Extension', true, 'jpeg,jpg,png');
		//$image->addValidator('MimeType', true, array('image/jpg', 'image/png', 'image/gif'));
		$image->addValidator(new Core_Validate_ImageType(array(IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF)));
		$image->setRequired(true);
		//$image->addDecorator(new Tab_Form_Decorator_HrSeparator());

		$this->addElement($image, 'image');
	}
	/**
	 *
	 * @return string
	 */
	private function getCancelUrl()
	{
		if($this->_is_edit)
		{
			return $this->_social->url('/contest/entry/list/id_contest/') . $this->_id_contest;
		}
		else
		{
			return $this->_social->pageUrl(array('target' => 'about'));
		}
	}
	
	private function initContestFields($id_contest)
	{
		$contestFieldsTable = new Core_Model_DbTable_EntryFields();
		$contestFields		= $contestFieldsTable->getListFieldsBelongToContest($id_contest);
		$fieldTypes			= Core_Model_DbTable_EntryFields::getListFieldTypes();
		$script = array();
		
		foreach($contestFields as $field)
		{
			$fieldType			= $fieldTypes[$field->type];			
			$fieldType['name']	= $field->id;
            
			$element			= $this->createElementByFieldType($fieldType, $field->is_required);
			if( $field->type == self::INDEX_FULL_NAME )
			{
				$element->setAttrib('data-field', 'name');
			}
			elseif($field->type == self::INDEX_FIRST_NAME )
			{
				$element->setAttrib('data-field', 'first_name');
			}
			elseif($field->type == self::INDEX_MIDDLE_NAME )
			{
				$element->setAttrib('data-field', 'middle_name');
			}
			elseif($field->type == self::INDEX_LAST_NAME )
			{
				$element->setAttrib('data-field', 'last_name');
			}			
			elseif($field->type == self::INDEX_EMAIL )
			{
				$element->setAttrib('data-field', 'email');
			}
			$script = array_merge($script, $this->createValidateScriptForField($field, $fieldType));
			$this->addElement($element);
		}
		
		if(!$this->_is_use_fullname)
		{
			$this->removeElement($this->_fullname_id);
			unset($script[self::FIELD_FULL_NAME]);
		}
		
		$this->setValidateScript($this->createValidateScriptForForm($script));
	}
	
	private function setValidateScript($script)
	{
		$this->_validate_script = $script;
	}
	
	public function getValidateScript()
	{
		return $this->_validate_script;
	}
	
	private function createValidateScriptForForm($scripts)
	{
		$body = '';
		foreach($scripts as $script)
		{
			if(is_array($script))
			{
				foreach($script as $scr)
				{
					$body.= $scr;
				}
			}
			else
			{
				$body.= $script;
			}
		}
		return $body;
	}
	
	private function createValidateScriptForField($field, $fieldType)
	{
		
		$script = array();
		switch($fieldType['type'])
		{
			case self::TYPE_TEXT:
				$script[$field->label] = $this->createValidateScriptForTextBox($field, $fieldType);
				break;
			case self::TYPE_GENDER:
			case self::TYPE_COUNTRY:
				$script[$field->label] = $this->createValidateScriptForComboBox($field);
				break;
			case self::TYPE_YES_NO:
				break;
		}
		return $script;
	}
	
	private function createValidateScriptForTextBox($field, $fieldType)
	{
		$script = array();
		
		if($field->is_required)
		{
$format	= '
   
			if(%1$s.val()=="")
			{
                showPopUpDialog({
                    content: "%2$s"
                });
				%1$s.focus();
                $("input[type=submit]").attr("disabled", false);
                $("button#reset").attr("disabled", false);
				return false;
			};
';
			$fieldID	=  $this->getFieldID($field->id);
			$script[]	= sprintf($format, $fieldID, $this->getErrorMessage('ERROR_EMPTY', $field->label));
		}
		
		if(isset($fieldType['validator']) && count($fieldType['validator']))
		{
			$validators = $fieldType['validator'];

			foreach($validators as $validator)
			{
				switch($validator[0])
				{
					case 'EmailAddress':
						$script[] = $this->createValidateEmailScript($field);
						break;
					case 'StringLength':
						$script[] = $this->createValidateLengthScript($field, $validator[1]['max']);
						break;
					case 'Regex':
						$script[] = $this->createValidateRegexScript($field, $validator[2][0], $fieldType);
						break;
					case 'Alnum':
						$script[] = $this->createValidateAlnumScript($field);
						break;
				}
			}
		}
		return $script;
	}
	
	private function getFieldID($fieldID)
	{
		$format = "$('#candidate-%d')";
		return sprintf($format, $fieldID);
	}
	
	private function createValidateScriptForComboBox($field)
	{
		$script = '';
		if($field->is_required)
		{
$format = '
   
			if(%1$s.val()=="-1")
			{
				showPopUpDialog({
                    content: "%2$s"
                });
				%1$s.focus();
                $("input[type=submit]").attr("disabled", false);
                $("button#reset").attr("disabled", false);
				return false;
			};
';
			$fieldID	=  $this->getFieldID($field->id);
			$script .= sprintf($format, $fieldID, $this->getErrorMessage('ERROR_SELECT', $field->label));
		}
		return $script;
	}
	
	private function createValidateEmailScript($field)
	{
		$script = '';
		$required_format = "if($.trim(%s.val())!=''){ %s }";
$format = '
   
		if(validateEmail($.trim(%1$s.val()))==false)
		{
			showPopUpDialog({
                content: "%2$s"
            });
			%1$s.focus();
            $("input[type=submit]").attr("disabled", false);
            $("button#reset").attr("disabled", false);
			return false;
		};
';
		$fieldID	=  $this->getFieldID($field->id);
		$script .= sprintf($format, $fieldID, $this->getErrorMessage('ERROR_INVALID', $field->label));
		
		if(!$field->is_required)
		{
			$script = sprintf($required_format, $fieldID, $script);
		}
		
		return $script;
	}
	
	private function createValidateLengthScript($field, $maxlength)
	{
		$script = '';
		
$format = '
   
		if(%1$s.val().length>%2$d){
			showPopUpDialog({
                content: "%3$s"
            });
			%1$s.focus();
            $("input[type=submit]").attr("disabled", false);
            $("button#reset").attr("disabled", false);
			return false;
		};
';
		$fieldID	=  $this->getFieldID($field->id);
		$script .= sprintf($format, $fieldID, $maxlength, $this->getErrorMessage('ERROR_LENGTH', $field->label, $maxlength));
		
		return $script;
	}
	
	private function createValidateAlnumScript($field)
	{
		$script = '';
		$required_format = "if($.trim(%s.val())!=''){ %s }";
        $format = '

                var alnumRegex = /^\w+$/i;
                if(!alnumRegex.test($.trim(%1$s.val())))
                {
                    showPopUpDialog({
                        content: "%2$s"
                    });
                    %1$s.focus();
                    $("input[type=submit]").attr("disabled", false);
                    $("button#reset").attr("disabled", false);
                    return false;
                }
        ';
		$fieldID	=  $this->getFieldID($field->id);
		$script .= sprintf($format, $fieldID, $this->getErrorMessage('ERROR_ALNUM', $field->label));
		
		if(!$field->is_required)
		{
			$script = sprintf($required_format, $fieldID, $script);
		}
		
		return $script;
	}
	private function createValidateRegexScript($field, $regex, $fieldType)
	{
		$script = '';
		$required_format = "if($.trim(%s.val())!=''){ %s }";
        $format = '
                var re = %2$s;
                if(!re.test($.trim(%1$s.val()))){
                    showPopUpDialog({
                        content: "%3$s"
                    });
                    %1$s.focus();
                    $("input[type=submit]").attr("disabled", false);
                    $("button#reset").attr("disabled", false);
                    return false;
                };
        ';
		$fieldID	=  $this->getFieldID($field->id);
		$script .= sprintf($format, $fieldID, $regex,  $this->getTranslator()->_($fieldType['regex_error']));
		
		if(!$field->is_required)
		{
			$script = sprintf($required_format, $fieldID, $script);
		}
		
		return $script;
	}
	
	/**
	 * Get list of args 
	 * 1st arg as error type
	 * @return type 
	 */
	private function getErrorMessage()
	{
		$args		= func_get_args();
		$errorType	= $this->getTranslator()->_($args[0]);
		$fieldNames = array();
		$data		= array_shift($args);
		
		foreach($args as $data)
		{
			$fieldNames[] = $this->getTranslator()->_($data);
		}
		
		return vsprintf($errorType, $fieldNames);
	}
	/**
	 *
	 * @param type $fieldType
	 * @param type $is_required
	 * @return type 
	 */
	private function createElementByFieldType($fieldType, $is_required)
	{
		$type = $this->getFieldType($fieldType['type']);
		
		$element = $this->createElement($type, $fieldType['name']);
		$element->setBelongsTo('candidate');
		$element->setLabel($this->getTranslator()->_($fieldType['label']));
		
		if($fieldType['label'] == self::FIELD_FULL_NAME)
		{
			$this->_fullname_id = $fieldType['name'];
		}
		
		if($fieldType['label'] == self::FIELD_FIRST_NAME)
		{
			$this->_is_use_fullname = false;
		}
		

		$arrayAtribs = array();
		
		if($is_required)
		{
			$element->setRequired(true);
			$arrayAtribs['required'] = true;
		}
		
		if(isset($fieldType['validator']) && count($fieldType['validator']))
		{
			$element->addValidators($fieldType['validator']);
			
			$validators = $fieldType['validator'];
			
			foreach($validators as $validator)
			{
				switch($validator[0])
				{
					case 'EmailAddress':
						$arrayAtribs['email'] = true;
						break;
//					case 'StringLength':
//						$arrayAtribs['maxlength'] = $validator[1]['max'];
//						break;
				}
			}
		}
		
		if(isset($fieldType['filter']))
		{
			foreach($fieldType['filter'] as $filter)
			{
				$element->addFilter($filter);
			}
		}
		
		if($fieldType['type']==self::TYPE_GENDER)
		{
			$gender = $this->getGender();
			
			$element->setMultiOptions($gender);
		}
		
		if($fieldType['type']==self::TYPE_COUNTRY)
		{
			$countriesTable = new Core_Model_DbTable_Countries();
			$countries		= array(-1 => $this->getTranslator()->_('DEFAULT_CHOOSE_A_COUNTRY'));  
			$countries		+= $countriesTable->getCountryList();
			$element->setMultiOptions($countries);
		}

		//jquery metadata dose not look exactly like json
		//double-quoted must be removed
		$validatorClass = str_replace('"','',json_encode($arrayAtribs));
		$element->setAttrib('class', $validatorClass);
        
        if(!empty($fieldType['class'])){
            $element->setAttrib('class', $fieldType['class']);
        }
        
		return $element;
		
	}
	
	public function getFieldType($intType)
	{
		switch($intType)
		{
			case self::TYPE_TEXT:
				return 'text';
				break;
			case self::TYPE_GENDER:
				return 'select';
				break;
			case self::TYPE_COUNTRY:
				return 'select';
				break;
			case self::TYPE_YES_NO:
				return 'radio';
				break;
			default:
				return 'text';
				break;
		}

	}
	
	public static function getGender()
	{
		return array(
				-1  => YouNet_Util::translate('LABEL_DEFAULT_SELECT'),
				0	=>YouNet_Util::translate('LABEL_MALE'),
				1	=>YouNet_Util::translate('LABEL_FEMALE')
			);
	}
	

}
